﻿using System;
using System.Linq.Expressions;
using Fabrication.Extensions;
using Fabrication.ValueProviders;

namespace Fabrication
{
    public static class DateRuleExtensions
    {
        public static IBuilderOptions<T> UseFutureDate<T>(this PropertySelector<T, DateTime> propertySelector, int maximumDays)
        {
            var provider = new FunctionValueProvider<T, DateTime>(x => DateTime.Today.AddDays(RandomNumberGenerator.GetInteger(1, maximumDays)).Date);
            return propertySelector.Use(provider);
        }

        public static IBuilderOptions<T> UseHistoricDate<T>(this PropertySelector<T, DateTime> propertySelector, int maximumDays)
        {
            var provider = new FunctionValueProvider<T, DateTime>(x => DateTime.Today.AddDays(RandomNumberGenerator.GetInteger(1, maximumDays) * -1).Date);
            return propertySelector.Use(provider);
        }

        public static IBuilderOptions<T> UseRange<T>(this PropertySelector<T, DateTime> propertySelector, int maximumDays)
        {
            var provider = new FunctionValueProvider<T, DateTime>(x => DateTime.Today.AddDays(RandomNumberGenerator.GetInteger(maximumDays - 1, maximumDays)).Date);
            return propertySelector.Use(provider);
        }

        public static IBuilderOptions<T> UseRange<T>(this PropertySelector<T, DateTime> propertySelector, DateTime firstDate, DateTime secondDate)
        {
            if (secondDate < firstDate)
            {
                var temp = firstDate;
                firstDate = secondDate;
                secondDate = temp;
            }

            var provider = new FunctionValueProvider<T, DateTime>(x => firstDate.AddDays(RandomNumberGenerator.GetInteger(0, Convert.ToInt32((secondDate - firstDate).TotalDays))).Date);
            return propertySelector.Use(provider);
        }

        public static IBuilderOptions<T> IsAfter<T>(this EnsurePropertySelector<T, DateTime> targetPropertySelector, Expression<Func<T, DateTime>> member)
        {
            var sourcePropertyName = member.GetPropertyName();
            var builderOptions = targetPropertySelector.BuilderOptions;
            builderOptions.AddEnsureRule<DateTime, DateTime>(typeof(T), sourcePropertyName, targetPropertySelector.PropertyName, x => x.AddDays(RandomNumberGenerator.GetInteger(1, 30)));
            return builderOptions;
        }

        public static IBuilderOptions<T> IsBefore<T>(this EnsurePropertySelector<T, DateTime> targetPropertySelector, Expression<Func<T, DateTime>> member)
        {
            var sourcePropertyName = member.GetPropertyName();
            var builderOptions = targetPropertySelector.BuilderOptions;
            builderOptions.AddEnsureRule<DateTime, DateTime>(typeof(T), sourcePropertyName, targetPropertySelector.PropertyName, x => x.AddDays(RandomNumberGenerator.GetInteger(1, 30) * -1));
            return builderOptions;
        }
    }
}